﻿using System.Reflection;
using BasicFramework.Components;
using BasicFramework.Entities;
using BasicFramework.Helper;

namespace BasicFramework.Factory
{
    public sealed class EntityFactory : Factory
    {
        EntityManager manager;

        public EntityFactory(EntityManager manager)
        {
            this.manager = manager;
        }

        public T Create<T>(string name) where T : Entity
        {
            Logger.Info("Creating " + name + " entity");
            // if we didn't pass an object array, we would enter an infinite recursive loop
            // since we would essentially be calling this method, which then calls this method.. etc.
            // where we actually wanted to call the method overload taking an object[] parameter list
            return Create<T>(new object[] { name });
        }

        public T Create<T>(string name, params IComponent[] components) where T : Entity
        {
            Logger.Info("Creating " + name + " entity");
            return Create<T>(new object[] { name, components });
        }

        // all the code inside this method could be replaced by 1 line, if the CF hadn't stripped System.Activator down to a bare minimum
        public T Create<T>(params object[] parameters) where T : Entity
        {
            ConstructorInfo bestMatch = GetBestMatchingConstructor(typeof(T), parameters);

            object obj = null;

            try
            {
                obj = bestMatch.Invoke(parameters);
            }
            catch (TargetInvocationException)
            {
                throw;
            }
            catch (TargetParameterCountException)
            {
                throw;
            }

            Entity entity = obj as Entity;

            entity.Manager = manager;
            manager.Add(entity);
            // TODO: Componenten der entität direkt erzeugen ?
            Logger.Info(entity.Name + " entity successfully created");

            return obj as T;
        }
    }
}
